import requests
from lxml import etree
import time
import datetime



def str2datetime(str_datetime: str, str_format: str = None) -> datetime:
    if str_format is None:
        str_format = '%Y-%m-%d %H:%M:%S'
    return datetime.datetime.strptime(str_datetime, str_format)


def Get_fre(data):
    month_to_int = {
        'Jan': '01',
        'Feb': '02',
        'Mar': '03',
        'Apr': '04',
        'May': '05',
        'Jun': '06',
        'Jul': '07',
        'Aug': '08',
        'Sep': '09',
        'Oct': '10',
        'Nov': '10',
        'Dec': '12',
    }
    all_trade_date_list = data.split('；')

    trade_date_min = 999999999999
    trade_date_max = 0
    frequent = 0
    total_count = len(all_trade_date_list)
    count_25 = 0
    if total_count >= 2:
        for each_data in all_trade_date_list:
            count_25+=1
            if count_25 >=25:
                break
            t_date, t_time, remain = str(each_data).split(' ')
            month_str, day_str, year_str = str(t_date).split('-')
            month_str = month_to_int[month_str]
            datetime_part1 = "{}-{}-{}".format(year_str, month_str, day_str)
            if remain == 'PM':
                hour, min, sec = str(t_time).split(':')
                if hour != '12':
                    hour = int(hour) + 12
                t_time = "{}:{}:{}".format(hour, min, sec)
            datetime_part2 = t_time
            datetime_str = "{} {}".format(datetime_part1, datetime_part2)
            tr_datetime = str2datetime(datetime_str)
            tr_datetime = tr_datetime.timetuple()
            timeStamp = int(time.mktime(tr_datetime))

            if timeStamp >= trade_date_max:
                trade_date_max = timeStamp
            if timeStamp <= trade_date_min:
                trade_date_min = timeStamp
        frequent = total_count / (trade_date_max - trade_date_min) * 3600
    return frequent


def Get_data(hash):
    print("開始獲取數據並進行初步處理")
    page_code = requests.get(url="https://etherscan.io/address/{}".format(hash),timeout=10).content
    time.sleep(1)
    dom = etree.HTML(page_code)
    balance = str()
    try:
        balance = str(dom.xpath('string(//div[contains(text(),"Balance:")]/following-sibling::div[1]/text())')) + \
                  str(dom.xpath(
                      'string(//div[contains(text(),"Balance:")]/following-sibling::div[1]/b[1]/text())')) + \
                  str(dom.xpath(
                      'string(//div[contains(text(),"Balance:")]/following-sibling::div[1]/b[1]/following-sibling::text())'))
        balance = float(balance.replace('\n', '').replace(' ', '').replace('Ether', '').replace(',', ''))

    except Exception:
        if balance.find('wei') >= 0:
            balance = 0
    all_trade_date = '；'.join(dom.xpath('//tbody/tr/td[3]/span[1]/@title'))
    if len(all_trade_date) == 0:
        all_trade_date = '；'.join(dom.xpath('//table[@class="table table-hover"]/tr/td[3]/span[1]/@title'))
    print("余额：{}".format(balance))

    fre = Get_fre(all_trade_date)
    print("频率:{}".format(fre))

    trade_count = str(dom.xpath('string(//span[@title="Normal Transactions"]/text())')).replace(' txns','')
    print("交易数:{}".format(trade_count))

    first_trade_hash = str(dom.xpath('string(//tbody/tr[1]/td[1]/a[1]/text())'))
    page_code2 = requests.get(url="https://etherscan.io/tx/{}".format(first_trade_hash), timeout=10).content
    time.sleep(1)
    dom2 = etree.HTML(page_code2)
    nonce = str(dom2.xpath('string(//span[@title="Transaction Nonce"]/text())'))
    print("nonce：{}".format(nonce))

    max_money = 0
    all_trade_money = dom.xpath('//tbody/tr/td[7]')
    for each in all_trade_money:
        try:
            money = each.xpath('string(./text())') + each.xpath('string(./b[1]/text())') + each.xpath('string(./b[1]/following-sibling::text())')
            money = float(money.replace('\n', '').replace(' Ether', '').replace(',', ''))
            if money > max_money:
                max_money = money
        except Exception:
            pass
    print("最大交易额度:{}".format(max_money))
    data = {'trade_count': int(trade_count), 'fre': fre, 'balance':float(balance), 'max_money': float(max_money), 'nonce': float(nonce)}
    return data


def Get_level(data):
    trade_count = data['trade_count']
    if trade_count < 100:
        u11 = 4
    elif trade_count >=100 and trade_count <10000:
        u11 = 6
    elif trade_count >= 10000:
        u11 = 8

    fre = data['fre']
    if fre < 0.006:
        u12 = 11
    elif fre >= 0.006 and fre <10:
        u12 = 17
    elif fre >= 10:
        u12 = 23

    balance = data['balance']
    if balance < 10:
        du3 = 7*0.1283*0.5267/3
    elif balance >=10 and balance < 1000:
        du3 = 15*0.2764*0.5267/3
    elif balance >= 1000:
        du3 = 30 * 0.5954*0.5267/3

    max_money = data['max_money']
    if max_money < 1:
        u41 = 1
    elif max_money>=1 and max_money <20:
        u41 = 1
    elif max_money > 20:
        u41 = 2

    nonce = data['nonce']
    if nonce < 100:
        u42 = 3
    elif nonce > 100 and nonce < 10000:
        u42 = 4
    elif nonce > 10000:
        u42 = 6

    du1 = (u11*0.25+u12*0.75)*0.3005/2
    du2 = 0.0945
    du4 = (u41*0.1632 + u42*0.5396 + 2*0.297)*0.1098/3
    D = pow((du1*du2*du3*du4), 1/4)

    if D >= 0.4070 and D < 0.4595:
        if D-0.4070 > 0.4595-D:
            result_level = 'B'
        else:
            result_level = 'C'
    elif D >= 0.4595 and D < 0.5109:
        if D-0.4595 > 0.5109-D:
            result_level = 'BB'
        else:
            result_level = 'B'
    elif D >= 0.5109 and D < 0.5804:
        if D-0.5109 > 0.5804-D:
            result_level = 'BB'
        else:
            result_level = 'A'
    elif D >= 0.5804 and D < 0.6548:
        if D-0.5804 > 0.6548-D:
            result_level = 'AA'
        else:
            result_level = 'A'
    else:
        result_level = 'C'

    return result_level



data = Get_data("0x1bb3a5dD6f51291149cFFdA66C1cE80B1F4a286F")
level = Get_level(data)
print("用戶最终等级为：{}".format(level))

